1
1

00:00:01,180  -->  00:00:04,670
<v Instructor>As we move towards the end of this section,</v>
2

2

00:00:04,670  -->  00:00:06,940
we need to learn about the big difference
3

3

00:00:06,940  -->  00:00:10,030
between the way primitive types and objects
4

4

00:00:10,030  -->  00:00:12,467
are stored and memory.
5

5

00:00:12,467  -->  00:00:15,760
And this is actually a very practical aspect
6

6

00:00:15,760  -->  00:00:20,290
and one that causes a lot of confusion in beginners.
7

7

00:00:20,290  -->  00:00:24,230
So let's actually start by writing some code this time
8

8

00:00:24,230  -->  00:00:27,660
to understand what the confusion actually is,
9

9

00:00:27,660  -->  00:00:29,280
so that I can then show you
10

10

00:00:29,280  -->  00:00:31,483
how it all works behind the scenes.
11

11

00:00:33,200  -->  00:00:35,240
So right now I'm not gonna explain
12

12

00:00:35,240  -->  00:00:38,290
how the code we will right now works,
13

13

00:00:38,290  -->  00:00:43,040
but I will just show you what the source of confusion is.
14

14

00:00:43,040  -->  00:00:44,470
But for now let's start with
15

15

00:00:44,470  -->  00:00:47,480
a simple example with primitives.
16

16

00:00:47,480  -->  00:00:50,310
And so remember primitives are like numbers,
17

17

00:00:50,310  -->  00:00:52,503
strings, Boolean's, et cetera.
18

18

00:00:53,720  -->  00:00:56,273
So simply setting the age to 30,
19

19

00:00:57,609  -->  00:01:01,453
and then I'm creating a old age variable.
20

20

00:01:02,370  -->  00:01:04,620
And this one I will set to the age
21

21

00:01:04,620  -->  00:01:07,920
because now it is my birthday basically.
22

22

00:01:07,920  -->  00:01:10,890
And so my age changes to 31,
23

23

00:01:10,890  -->  00:01:14,130
but I still wanted to preserve my old age here
24

24

00:01:14,130  -->  00:01:15,490
in this variable.
25

25

00:01:15,490  -->  00:01:16,600
Okay?
26

26

00:01:16,600  -->  00:01:20,217
So let's log the results to the console now.
27

27

00:01:20,217  -->  00:01:25,217
And they should be pretty much what we expect at this point.
28

28

00:01:25,770  -->  00:01:30,350
So you see that my current age is 31 because, well,
29

29

00:01:30,350  -->  00:01:34,640
I changed the original one from 30 to 31.
30

30

00:01:34,640  -->  00:01:38,190
But the old age is still 30 here.
31

31

00:01:38,190  -->  00:01:41,880
And that's because I set it here at this point of the code
32

32

00:01:42,800  -->  00:01:46,770
to age, which was still 30 at this point.
33

33

00:01:46,770  -->  00:01:51,410
And so then changing the age here from 30 to 31
34

34

00:01:51,410  -->  00:01:55,120
did of course not affect the old age variable again.
35

35

00:01:55,120  -->  00:01:59,773
Again because at this point here age was still 30.
36

36

00:02:01,063  -->  00:02:06,063
All right, so here, hopefully there is not much confusion,
37

37

00:02:06,120  -->  00:02:09,000
everything works just as expected.
38

38

00:02:09,000  -->  00:02:12,913
But now let's create another scenario which has an object.
39

39

00:02:14,470  -->  00:02:17,563
So I'm simply going to create an object for me,
40

40

00:02:19,080  -->  00:02:23,443
with the name of Jonas and age 30.
41

41

00:02:25,220  -->  00:02:28,000
And now let's copy this object
42

42

00:02:28,000  -->  00:02:30,560
because let's say that I have a friend
43

43

00:02:30,560  -->  00:02:32,660
who's also called Jonas.
44

44

00:02:32,660  -->  00:02:36,510
And so instead of creating a brand new object from scratch,
45

45

00:02:36,510  -->  00:02:39,080
I would just copy the me object.
46

46

00:02:39,080  -->  00:02:43,637
So const Friend equals Me.
47

47

00:02:45,680  -->  00:02:46,530
Okay?
48

48

00:02:46,530  -->  00:02:50,240
And so now both the name and the age are the same,
49

49

00:02:50,240  -->  00:02:52,980
but let's say that we have different ages.
50

50

00:02:52,980  -->  00:02:56,120
And so let's change the age of my friend
51

51

00:02:57,220  -->  00:03:00,920
and that's pretty straightforward, right?
52

52

00:03:00,920  -->  00:03:04,610
So let's say that he is 27 years old.
53

53

00:03:04,610  -->  00:03:09,433
But of course we did not change me.age, right?
54

54

00:03:10,410  -->  00:03:15,410
So let's now take a look at both of them in the console.
55

55

00:03:16,980  -->  00:03:18,023
So first my friend,
56

56

00:03:20,850  -->  00:03:25,743
so that's the Friend object and then also Me,
57

57

00:03:26,730  -->  00:03:29,850
or we could say Jonas, it doesn't really matter.
58

58

00:03:29,850  -->  00:03:34,190
But what matters is that we will see the Me object
59

59

00:03:34,190  -->  00:03:37,610
and what do we think will happen now?
60

60

00:03:37,610  -->  00:03:39,800
So let me show it to you.
61

61

00:03:39,800  -->  00:03:43,290
And now we get that both me and my friend
62

62

00:03:43,290  -->  00:03:45,847
have the age of 27.
63

63

00:03:45,847  -->  00:03:49,530
And that looks a little bit strange because all we did
64

64

00:03:49,530  -->  00:03:53,540
was to change the age of the friend, right?
65

65

00:03:53,540  -->  00:03:57,760
Nowhere here, I have me.age equals 27,
66

66

00:03:57,760  -->  00:04:02,140
but still for myself, so here at the Me object,
67

67

00:04:02,140  -->  00:04:04,840
the age is also 27.
68

68

00:04:04,840  -->  00:04:08,980
And so that is what I mean by source of confusion.
69

69

00:04:08,980  -->  00:04:10,200
And so in this video,
70

70

00:04:10,200  -->  00:04:13,233
let's now find out why it works this way.
71

71

00:04:14,720  -->  00:04:18,700
Now, before we can understand the code that we just wrote,
72

72

00:04:18,700  -->  00:04:21,450
we need to review some basics here.
73

73

00:04:21,450  -->  00:04:23,363
First, we need to remember about
74

74

00:04:23,363  -->  00:04:25,900
JavaScripts primitive data types,
75

75

00:04:25,900  -->  00:04:30,900
which are number, string, Boolean, undefined, null, symbol,
76

76

00:04:31,060  -->  00:04:32,860
and BigInt.
77

77

00:04:32,860  -->  00:04:36,660
Then everything else are basically objects.
78

78

00:04:36,660  -->  00:04:40,900
So objects created with the object literal, arrays
79

79

00:04:40,900  -->  00:04:44,670
and even functions are all objects.
80

80

00:04:44,670  -->  00:04:48,660
Now, when we're talking about memory and memory management,
81

81

00:04:48,660  -->  00:04:52,010
it's usual to call primitives, primitive types
82

82

00:04:52,010  -->  00:04:56,260
and objects reference types because of the different way
83

83

00:04:56,260  -->  00:04:58,573
in which they are stored in memory.
84

84

00:04:59,410  -->  00:05:03,810
Next, we need to remember about the JavaScript engine.
85

85

00:05:03,810  -->  00:05:07,330
So the engine has two components, the call stack,
86

86

00:05:07,330  -->  00:05:11,470
where functions are executed and to heap where objects
87

87

00:05:11,470  -->  00:05:13,780
are stored in memory.
88

88

00:05:13,780  -->  00:05:16,710
And that's right, all of objects,
89

89

00:05:16,710  -->  00:05:19,510
or in other words, reference types
90

90

00:05:19,510  -->  00:05:23,020
will get stored right in the memory heap.
91

91

00:05:23,020  -->  00:05:26,780
And I mentioned that when we first talked about the engine,
92

92

00:05:26,780  -->  00:05:31,100
but now you will finally learn how that actually works.
93

93

00:05:31,100  -->  00:05:35,010
On the other hand, primitives or primitive types
94

94

00:05:35,010  -->  00:05:37,640
are stored in the call stack.
95

95

00:05:37,640  -->  00:05:40,650
And with that, I mean that primitive types
96

96

00:05:40,650  -->  00:05:43,680
are stored in the execution contexts
97

97

00:05:43,680  -->  00:05:45,830
in which they are declared.
98

98

00:05:45,830  -->  00:05:47,960
But for the sake of simplicity,
99

99

00:05:47,960  -->  00:05:50,220
let's ignore that detail now.
100

100

00:05:50,220  -->  00:05:52,600
And simply say that primitive types
101

101

00:05:52,600  -->  00:05:54,890
are stored in a call stack
102

102

00:05:54,890  -->  00:05:58,850
because that's where execution context run.
103

103

00:05:58,850  -->  00:06:03,030
All right, but now how does all that actually work?
104

104

00:06:03,030  -->  00:06:06,060
And why did our code example earlier behave
105

105

00:06:06,060  -->  00:06:08,220
in that weird way?
106

106

00:06:08,220  -->  00:06:09,953
Well, let's find out.
107

107

00:06:11,380  -->  00:06:14,860
So here we have the two code examples from earlier,
108

108

00:06:14,860  -->  00:06:19,380
as well as the engine with call stack and heap.
109

109

00:06:19,380  -->  00:06:24,020
And let's start by looking at the primitive values example.
110

110

00:06:24,020  -->  00:06:28,580
So when we declare a variable like age equals 30,
111

111

00:06:28,580  -->  00:06:32,060
what actually happens inside the JavaScript engine
112

112

00:06:32,060  -->  00:06:33,453
and the computer's memory?
113

113

00:06:34,390  -->  00:06:37,460
Well, first JavaScript will create
114

114

00:06:37,460  -->  00:06:42,140
a so-called unique identifier with the variable name.
115

115

00:06:42,140  -->  00:06:45,450
Then a piece of memory will be allocated
116

116

00:06:45,450  -->  00:06:49,778
with a certain address, so 0001 in this example,
117

117

00:06:49,778  -->  00:06:54,180
and finally the value would be stored in memory
118

118

00:06:54,180  -->  00:06:56,310
at the specified address.
119

119

00:06:56,310  -->  00:06:58,260
So in this case, the value 30
120

120

00:06:58,260  -->  00:07:02,463
will be specified at memory address 0001.
121

121

00:07:03,360  -->  00:07:06,400
And remember this all happens in a call stack
122

122

00:07:06,400  -->  00:07:08,653
where primitive values are stored.
123

123

00:07:09,570  -->  00:07:12,830
Now what's extremely important to understand here
124

124

00:07:12,830  -->  00:07:17,070
is that the identifier actually points to the address
125

125

00:07:17,070  -->  00:07:19,690
and not to the value itself.
126

126

00:07:19,690  -->  00:07:24,010
So we would say that the age variable is equal to 30,
127

127

00:07:24,010  -->  00:07:28,680
but in fact, age is equal to the memory address 0001,
128

128

00:07:30,420  -->  00:07:33,730
which holds the value of 30, all right?
129

129

00:07:33,730  -->  00:07:35,310
And this subtle distinction
130

130

00:07:35,310  -->  00:07:38,380
is very important to keep in mind.
131

131

00:07:38,380  -->  00:07:41,420
Now, in the next line, we declare old age
132

132

00:07:41,420  -->  00:07:43,540
to be equal to age.
133

133

00:07:43,540  -->  00:07:48,240
So knowing that a variable actually holds a memory address,
134

134

00:07:48,240  -->  00:07:51,200
what should old age look like?
135

135

00:07:51,200  -->  00:07:55,290
Well, it will simply point to the same memory address
136

136

00:07:55,290  -->  00:07:57,080
as the age variable.
137

137

00:07:57,080  -->  00:08:02,080
And so it will look like old age, is simply 30 as well.
138

138

00:08:02,140  -->  00:08:07,140
Great, but now in the next line, we set eight to 31.
139

139

00:08:07,160  -->  00:08:09,060
So what will happen then?
140

140

00:08:09,060  -->  00:08:12,070
The value at address 0001
141

141

00:08:12,070  -->  00:08:15,270
will certainly not become 31
142

142

00:08:15,270  -->  00:08:18,560
because that would change old age as well,
143

143

00:08:18,560  -->  00:08:21,560
since they both point to the same address.
144

144

00:08:21,560  -->  00:08:24,480
So that would make no sense at all.
145

145

00:08:24,480  -->  00:08:28,590
Also the value at a certain memory address is immutable,
146

146

00:08:28,590  -->  00:08:32,000
or in other words, it cannot be changed.
147

147

00:08:32,000  -->  00:08:34,630
So instead what's going to happen here
148

148

00:08:34,630  -->  00:08:38,190
is that a new piece of memory is allocated.
149

149

00:08:38,190  -->  00:08:42,477
So it's created and the age identifier now simply points
150

150

00:08:42,477  -->  00:08:47,023
to the new address, which is holding the new value of 31,
151

151

00:08:47,920  -->  00:08:48,753
all right?
152

152

00:08:48,753  -->  00:08:51,060
And that's why when we lock both
153

153

00:08:51,060  -->  00:08:53,720
or variables to the console in the end,
154

154

00:08:53,720  -->  00:08:58,050
they both return exactly values that we expect.
155

155

00:08:58,050  -->  00:09:02,200
Now with reference values, things work a bit differently,
156

156

00:09:02,200  -->  00:09:05,230
which is the reason why this example gave us
157

157

00:09:05,230  -->  00:09:09,910
that unexpected, weird behavior earlier in practice.
158

158

00:09:09,910  -->  00:09:14,590
So what's the origin of this weird unexpected result?
159

159

00:09:14,590  -->  00:09:19,590
Well, when a new object is created such as this Me object,
160

160

00:09:19,790  -->  00:09:21,930
it is stored in the heap.
161

161

00:09:21,930  -->  00:09:25,030
And such as before there is a memory address
162

162

00:09:25,030  -->  00:09:27,360
and then the value itself.
163

163

00:09:27,360  -->  00:09:29,710
Now in the case of reference values
164

164

00:09:29,710  -->  00:09:33,300
like this Me object the Me identifier
165

165

00:09:33,300  -->  00:09:35,920
does actually not point directly
166

166

00:09:35,920  -->  00:09:39,790
to this newly created memory address in the heap.
167

167

00:09:39,790  -->  00:09:43,360
So in this example, D30F,
168

168

00:09:43,360  -->  00:09:46,890
instead, it will point to a new piece of memory
169

169

00:09:46,890  -->  00:09:49,350
that's created in the stack.
170

170

00:09:49,350  -->  00:09:53,247
And this new piece of memory will then point to the object
171

171

00:09:53,247  -->  00:09:58,247
that's in the heap by using the memory address as its value.
172

172

00:09:59,220  -->  00:10:02,620
In other words, the piece of memory in the call stack
173

173

00:10:02,620  -->  00:10:06,290
has a reference to the piece of memory in the heap,
174

174

00:10:06,290  -->  00:10:09,810
which holds or Me object, okay?
175

175

00:10:09,810  -->  00:10:13,670
And that's the reason why we call objects reference types
176

176

00:10:13,670  -->  00:10:15,300
in this context.
177

177

00:10:15,300  -->  00:10:19,650
So again, when we declare a variable as an object,
178

178

00:10:19,650  -->  00:10:21,930
an identifier is created,
179

179

00:10:21,930  -->  00:10:25,130
which points to a piece of memory in the stack,
180

180

00:10:25,130  -->  00:10:29,010
which in turn points to a piece of memory in the heap.
181

181

00:10:29,010  -->  00:10:32,770
And that is where the object is actually stored.
182

182

00:10:32,770  -->  00:10:35,870
And it works this way because objects might be
183

183

00:10:35,870  -->  00:10:39,230
too large to be stored in the stack.
184

184

00:10:39,230  -->  00:10:42,210
Instead they are stored in the heap,
185

185

00:10:42,210  -->  00:10:45,620
which is like an almost unlimited memory pool.
186

186

00:10:45,620  -->  00:10:48,060
And the stack just keeps a reference
187

187

00:10:48,060  -->  00:10:51,610
to where the object is actually stored in the heap
188

188

00:10:51,610  -->  00:10:54,363
so that it can find it whenever necessary.
189

189

00:10:55,260  -->  00:10:57,390
Now, moving on in the code,
190

190

00:10:57,390  -->  00:11:00,540
we create a new variable called Friend
191

191

00:11:00,540  -->  00:11:03,900
that we set equal to the Me object.
192

192

00:11:03,900  -->  00:11:06,340
So what will happen here?
193

193

00:11:06,340  -->  00:11:09,570
Well, just like with primitive values,
194

194

00:11:09,570  -->  00:11:11,760
the Friend identifier will point
195

195

00:11:11,760  -->  00:11:16,560
to the exact same memory address as the Me identifier.
196

196

00:11:16,560  -->  00:11:20,000
And again, that address contains the reference,
197

197

00:11:20,000  -->  00:11:23,280
which then points to the object itself.
198

198

00:11:23,280  -->  00:11:27,010
And like this the Friend object is now essentially
199

199

00:11:27,010  -->  00:11:30,290
the exact same as the Me object.
200

200

00:11:30,290  -->  00:11:32,313
Do you see that here in the diagram?
201

201

00:11:33,230  -->  00:11:35,690
So here comes the interesting part
202

202

00:11:35,690  -->  00:11:38,870
because now we're actually gonna change a property
203

203

00:11:38,870  -->  00:11:43,870
in the Friend object by setting friend.age to 27.
204

204

00:11:44,420  -->  00:11:46,840
So what happens then is that the object
205

205

00:11:46,840  -->  00:11:51,800
is found in the heap, and the 30 is changed to 27.
206

206

00:11:51,800  -->  00:11:52,970
Great.
207

207

00:11:52,970  -->  00:11:56,410
And by the way, even though we defined the Friend variable
208

208

00:11:56,410  -->  00:12:01,170
as a constant, we can actually still manipulate the object
209

209

00:12:01,170  -->  00:12:03,100
without problems.
210

210

00:12:03,100  -->  00:12:06,180
And when we think about that, it makes sense
211

211

00:12:06,180  -->  00:12:09,840
because we're actually not changing the value in memory
212

212

00:12:09,840  -->  00:12:14,810
for the Friend identifier, it is still D30F.
213

213

00:12:14,810  -->  00:12:17,440
So the reference to the object.
214

214

00:12:17,440  -->  00:12:20,800
All we did was to change the value in the heap,
215

215

00:12:20,800  -->  00:12:22,690
and that's not a problem.
216

216

00:12:22,690  -->  00:12:26,230
So it's a misconception that all variables declared
217

217

00:12:26,230  -->  00:12:28,920
with const are immutable.
218

218

00:12:28,920  -->  00:12:32,610
In fact, that is only true for primitive values,
219

219

00:12:32,610  -->  00:12:35,200
but not for reference values.
220

220

00:12:35,200  -->  00:12:39,440
So keep that in mind, whenever you're working with const.
221

221

00:12:39,440  -->  00:12:43,000
Anyway, as we lock the Friend variable to the console,
222

222

00:12:43,000  -->  00:12:47,690
we get the age of 27, just as we said it before.
223

223

00:12:47,690  -->  00:12:50,350
But then when we lock the Me object,
224

224

00:12:50,350  -->  00:12:52,580
we get that weird behavior
225

225

00:12:52,580  -->  00:12:56,690
that we could previously not explain and not understand.
226

226

00:12:56,690  -->  00:12:59,750
But with everything that we learned in this lecture,
227

227

00:12:59,750  -->  00:13:01,520
it actually now makes sense
228

228

00:13:01,520  -->  00:13:05,950
that in the Me object, age is now also 27,
229

229

00:13:05,950  -->  00:13:10,100
even though we never changed me.age directly.
230

230

00:13:10,100  -->  00:13:13,410
And the reason for this, as we can see in this slide
231

231

00:13:13,410  -->  00:13:16,430
is the fact that Me and Friend
232

232

00:13:16,430  -->  00:13:21,400
actually point to the exact same object in the memory heap.
233

233

00:13:21,400  -->  00:13:24,370
So whenever we change something in this object,
234

234

00:13:24,370  -->  00:13:28,490
it will always be reflected in Friend and in Me.
235

235

00:13:28,490  -->  00:13:30,430
So in both these objects.
236

236

00:13:30,430  -->  00:13:34,040
So these are basically just two different identifiers
237

237

00:13:34,040  -->  00:13:36,960
pointing to the exact same value.
238

238

00:13:36,960  -->  00:13:40,907
And once again, that value is the memory address D30F
239

239

00:13:42,750  -->  00:13:46,800
which points to the reference in the memory heap.
240

240

00:13:46,800  -->  00:13:49,430
And one important implication of this
241

241

00:13:49,430  -->  00:13:53,330
is that whenever you think that you're copying an object,
242

242

00:13:53,330  -->  00:13:55,950
you're really just creating a new variable
243

243

00:13:55,950  -->  00:13:59,050
that points to the exact same object.
244

244

00:13:59,050  -->  00:14:01,380
And this has huge implications
245

245

00:14:01,380  -->  00:14:04,280
for the way JavaScript works in practice.
246

246

00:14:04,280  -->  00:14:06,760
And we will see that in the next video
247

247

00:14:06,760  -->  00:14:08,670
and throughout the course.
248

248

00:14:08,670  -->  00:14:11,450
Now there are actually ways around this,
249

249

00:14:11,450  -->  00:14:13,600
as we will also learn later.
250

250

00:14:13,600  -->  00:14:17,020
but in general, this is how reference values work
251

251

00:14:17,020  -->  00:14:18,580
in JavaScript.
252

252

00:14:18,580  -->  00:14:21,370
So make sure to really understand this,
253

253

00:14:21,370  -->  00:14:25,170
as well as the implications that this behavior has,
254

254

00:14:25,170  -->  00:14:28,620
even if that means that you have to re-watch this lecture
255

255

00:14:28,620  -->  00:14:33,570
or at least the explanation of this slide, all right?
256

256

00:14:33,570  -->  00:14:36,570
Then once you really understand what happened here,
257

257

00:14:36,570  -->  00:14:40,260
in this example, let's understand primitive values
258

258

00:14:40,260  -->  00:14:43,430
and reference values even better in practice
259

259

00:14:43,430  -->  00:14:44,843
in the next lecture.
260

260

00:14:45,900  -->  00:14:49,750
But before we do that, let me just quickly take a second
261

261

00:14:49,750  -->  00:14:52,920
and mention a three more, really big topics
262

262

00:14:52,920  -->  00:14:56,100
about how JavaScript works behind the scenes
263

263

00:14:56,100  -->  00:14:58,250
that will not be in the section,
264

264

00:14:58,250  -->  00:15:02,400
but closer to where we actually need to learn about them.
265

265

00:15:02,400  -->  00:15:06,220
For example, one fundamental concept of JavaScript
266

266

00:15:06,220  -->  00:15:08,710
is prototypal inheritance.
267

267

00:15:08,710  -->  00:15:10,690
But we will only talk about that
268

268

00:15:10,690  -->  00:15:14,610
in the object oriented programming section of this course.
269

269

00:15:14,610  -->  00:15:18,110
Because it doesn't make sense to learn about this now
270

270

00:15:18,110  -->  00:15:20,550
only to then forget it all
271

271

00:15:20,550  -->  00:15:23,083
until we finally reach that section.
272

272

00:15:23,960  -->  00:15:28,930
The same is true for a detailed lecture on the event loop.
273

273

00:15:28,930  -->  00:15:32,720
So I already introduced the event loop in this section,
274

274

00:15:32,720  -->  00:15:36,080
but in the section about asynchronous JavaScript,
275

275

00:15:36,080  -->  00:15:38,010
we will dive really deep into
276

276

00:15:38,010  -->  00:15:40,370
how exactly the event loop works
277

277

00:15:40,370  -->  00:15:42,910
and why it's such a fundamental piece
278

278

00:15:42,910  -->  00:15:44,393
of the JavaScript engine.
279

279

00:15:45,270  -->  00:15:47,390
Finally, we will have lectures on
280

280

00:15:47,390  -->  00:15:51,100
how the DOM actually works behind the scenes too.
281

281

00:15:51,100  -->  00:15:52,430
And that's going to be
282

282

00:15:52,430  -->  00:15:55,530
in the advanced DOM and events section
283

283

00:15:55,530  -->  00:15:57,160
so that you can then apply
284

284

00:15:57,160  -->  00:16:00,000
what you learned there right away.
285

285

00:16:00,000  -->  00:16:01,190
Okay?
286

286

00:16:01,190  -->  00:16:03,893
And with that being said, let's now move on.

